<template>
  {{ search }}
  <el-table
    v-loading="!getTableData?.length"
    :data="getTableData"
    style="width: 100%"
    :border="config.border"
    :height="config.height"
    :stripe="config.stripe"
    :max-height="config.maxHeight"
    :show-summary="config.showSummary"
    :highlight-current-row="config.singleChoiceHigHlight"
    @selection-change="handleSelectionChange"
    @current-change="handleCurrentChange"
    :span-method="objectSpanMethod"
  >
    <!-- 静态列，包括序号、多选、展开行 -->
    <template
      v-for="item in config.staticColumn"
      :key="item.type"
    >
      <el-table-column
        v-if="item.type==='selection'"
        :type="item.type"
        :width="item.width"
        :selectable="selectable"
      />
      <el-table-column
        v-else
        :type="item.type"
        :width="item.width"
      >
        <!-- 展开行 -->
        <template
          v-if="item.type==='expand'"
          #default="scope"
        >
          <slot
            name="expand"
            :data="scope.row"
          />
        </template>
      </el-table-column>
    </template>

    <template
      v-for="item in header"
      :key="item.label"
    >
      <template v-if="item.children?.length">
        <el-table-column :label="item.label">
          <template
            v-for="(subItem, index) in item.children"
            :key="index"
          >
            <template v-if="subItem.children?.length">
              <el-table-column :label="subItem.label">
                <TableItem
                  v-for="_subItem in subItem.children"
                  :key="_subItem.prop"
                  :data="_subItem"
                  v-model:search="search"
                >
                  <template
                    v-if="_subItem?.slotName"
                    #[_subItem.slotName]="{data}"
                  >
                    <slot
                      :name="_subItem.slotName"
                      :data="data"
                    />
                  </template>
                </TableItem>
              </el-table-column>
            </template>
            <TableItem
              v-else
              :data="subItem"
              v-model:search="search"
            >
              <template
                v-if="subItem?.slotName"
                #[subItem.slotName]="{data}"
              >
                <slot
                  :name="subItem.slotName"
                  :data="data"
                />
              </template>
            </TableItem>
          </template>
        </el-table-column>
      </template>
      <TableItem
        v-else
        :data="item"
        v-model:search="search"
      >
        <template
          v-if="item?.slotName"
          #[item.slotName]="{data}"
        >
          <slot
            :name="item.slotName"
            :data="data"
          />
        </template>
      </TableItem>
    </template>
  </el-table>
  <!-- 分页 -->
  <br>
  <Pagination
    v-if="pagination"
    :pagination="pagination"
    @handleSizeChange="handleSizeChange"
    @handleCurrentPageChange="handleCurrentPageChange"
  />
</template>

<script lang="ts" setup>
import type { TableColumnCtx } from 'element-plus/es/components/table/src/table-column/defaults'
import type { InitData, Header, Config, Pagination, SpanMethodProps } from './typing/table'
import { getMergeData } from '@/utils/tableMerge'
interface Props {
  tableData:InitData[]
  header: Header[]
  config:Config
  selectable: Function
  pagination:Pagination
}
const props = defineProps<Props>()

// 搜索框
const search = ref('')

const mergeData = computed(async () => {
  const { ranksMerge } = props.config
  let result:InitData[] = []
  if (props.tableData?.length) {
    result = await (ranksMerge?.isMerge && ranksMerge?.data && getMergeData(props.tableData, {
      ...ranksMerge.data
    })) || props.tableData
  }
  return result
})

const filterData = computed(async () => {
  const { searchProp } = props.config
  const searchVal = search.value // search.value提上来写，直接写在filter里无法监控
  const val = await mergeData.value
  if (!searchProp) return val
  const data = val.filter((data) =>
    !searchVal ||
      data[searchProp].toLowerCase().includes(searchVal.toLowerCase())
  )
  return data
})
const getTableData = ref<InitData[]>()

watchEffect(async () => {
  getTableData.value = await filterData.value
})

const emit = defineEmits(['handleSelectionChange', 'handleCurrentChange', 'handleSizeChange', 'handleCurrentPageChange'])

// 多选获取数据
const handleSelectionChange = (val: InitData[]) => {
  // multipleSelection.value = val
  const hasCheckbox = props.config.staticColumn?.find(item => item.type === 'selection')
  // console.log(hasCheckbox)
  if (!hasCheckbox) return () => {}
  emit('handleSelectionChange', val)
}

// 点击行获取数据
const handleCurrentChange = (val: InitData | undefined) => {
  if (!props.config?.singleChoiceHigHlight) return
  emit('handleCurrentChange', val)
}

// 判断某一行的checkBox是否能禁选
const selectable = (row: any, index:number) => {
  return props.selectable(row)
}

// 过滤，勿动
const filterHandler = (
  value: string,
  row: InitData,
  column: TableColumnCtx<InitData>
) => {
  const property = column.property
  return row[property] === value
}

// 分页相关
const handleSizeChange = (val: number) => {
  emit('handleSizeChange', val)
}
const handleCurrentPageChange = (val: number) => {
  emit('handleCurrentPageChange', val)
}
// 合并控制
const objectSpanMethod = ({
  row,
  column,
  rowIndex,
  columnIndex
}: SpanMethodProps) => {
  if (!props.config.ranksMerge) return
  if (row?.merge) {
    const { row: rowData, col } = row?.merge
    if (rowData) {
      const rowItem = rowData.find((item: { key: string; }) => item.key === column.property)
      if (rowIndex === rowItem?.mergeFirstRow) {
        return {
          rowspan: rowItem?.rowLen + 1,
          colspan: 1
        }
      }
      if (rowItem?.hidden) {
        return {
          rowspan: 0,
          colspan: 0
        }
      }
    }

    if (col) {
      const { colLen, mergeFirstColIndex } = col
      if (columnIndex === mergeFirstColIndex) {
        return [1, colLen]
      }
      if (columnIndex > mergeFirstColIndex && columnIndex < mergeFirstColIndex + colLen) {
        return [0, 0]
      }
    }
  }
}

</script>
<style lang="scss" scoped>
  :deep(.hiddenFilter){
    .el-table__column-filter-trigger{
      display: none;
    }
  }
</style>
